﻿using DG.Tweening;
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 玩家
/// </summary>
public class Player : MonoBehaviour
{
    private Rigidbody mRigidboy;
    private float mMaxAccumulatingTime = 3;
    private Transform mCenterOfGravity;
    private float mFactoer = 4;
    private Animator mAnimator;
    private Material mBodyMaterial;
    private Material mHeadMaterial;
    private float mDissolutionTime = 3;

    private Tweener mAccumulatingTweener;
    private float mStartAccumulatingTime = 0;
    private Vector3 mJumpDirection = Vector3.zero;
    // Start is called before the first frame update
    void Start()
    {
        mRigidboy = GetComponent<Rigidbody>();
        mCenterOfGravity = transform.Find("CenterOfGravity");
        mRigidboy.centerOfMass = mCenterOfGravity.localPosition;
        mAnimator = GetComponent<Animator>();
        mBodyMaterial = transform.Find("Body").GetComponent<MeshRenderer>().material;
        mHeadMaterial = transform.Find("Head").GetComponent<MeshRenderer>().material;
        EventCenter.GetInstance().AddEventListener("Start Accumulating", StartAccumulating);
        EventCenter.GetInstance().AddEventListener("End Accumulating", EndAccumulating);
        EventCenter.GetInstance().AddEventListener("Land On Platform", LandOnPlatform);
        EventCenter.GetInstance().AddEventListener("Land On Ground", LandOnGround);
        EventCenter.GetInstance().AddEventListener<Vector3>("Set Jump Direction", SetJumpDirection);
    }

    private void OnDestroy()
    {
        EventCenter.GetInstance().RemoveEventListener("Start Accumulating", StartAccumulating);
        EventCenter.GetInstance().RemoveEventListener("End Accumulating", EndAccumulating);
        EventCenter.GetInstance().RemoveEventListener("Land On Platform", LandOnPlatform);
        EventCenter.GetInstance().RemoveEventListener("Land On Ground", LandOnGround);
        EventCenter.GetInstance().RemoveEventListener<Vector3>("Set Jump Direction", SetJumpDirection);
    }
    /// <summary>
    /// 重置数据
    /// </summary>
    public void ResetData()
    {
        mStartAccumulatingTime = 0;
        mJumpDirection = Vector3.zero;
        mAccumulatingTweener = null;
        mHeadMaterial.SetFloat("_dissolution_strength", 0);
        mBodyMaterial.SetFloat("_dissolution_strength", 0);
    }
    /// <summary>
    /// 开始蓄力
    /// </summary>
    private void StartAccumulating()
    {
        if (!GameManager.GetInstance().isLose)
        {
            mStartAccumulatingTime = Time.realtimeSinceStartup;
            mAccumulatingTweener = DOTween.To(() => transform.localScale, (scale) => transform.localScale = scale, new Vector3(0.1f, 0.1f, 0.1f), mMaxAccumulatingTime);
        }
    }
    /// <summary>
    /// 结束蓄力
    /// </summary>
    private void EndAccumulating()
    {
        if (mStartAccumulatingTime != 0 && !GameManager.GetInstance().isLose)
        {
            float accumulatingTime = Time.realtimeSinceStartup - mStartAccumulatingTime;
            accumulatingTime = accumulatingTime > mMaxAccumulatingTime ? mMaxAccumulatingTime : accumulatingTime;
            mStartAccumulatingTime = 0;
            mAccumulatingTweener.Kill();
            mAccumulatingTweener = null;
            transform.localScale = new Vector3(0.2f, 0.2f, 0.2f);
            Jump(accumulatingTime);
        }
    }
    /// <summary>
    /// 设置跳跃方向 45度起跳
    /// </summary>
    /// <param name="nextPlatformPos"></param>
    private void SetJumpDirection(Vector3 nextPlatformPos)
    {
        mJumpDirection = nextPlatformPos - transform.position;
        mJumpDirection.y = 0;
        mJumpDirection = (mJumpDirection.normalized + Vector3.up).normalized;
    }
    /// <summary>
    /// 跳跃
    /// </summary>
    private void Jump(float accumulatingTime)
    {
        mAnimator.SetTrigger("Rotate");
        // 最低起跳距离为mJumpDirection * mFactoer
        mRigidboy.AddForce(mJumpDirection * (accumulatingTime + 1) * mFactoer, ForceMode.Impulse);
        InputManager.GetInstance().isOpen = false;
    }
    /// <summary>
    /// 落在平台上
    /// </summary>
    private void LandOnPlatform()
    {
        GameManager.GetInstance().isNextRound = false;
        GameManager.GetInstance().isPlatformReady = false;
        GameManager.GetInstance().AddScore(1);
        MonoManager.GetInstance().StartCoroutine(ReadyForNextRound(1));
    }
    /// <summary>
    /// 落在地上
    /// </summary>
    private void LandOnGround()
    {
        ulong dissolutionStrength = 0;
        DOTween.To(() => dissolutionStrength, (value) =>
        {
            float strength = value * 1.0f / 100;
            mHeadMaterial.SetFloat("_dissolution_strength", strength);
            mBodyMaterial.SetFloat("_dissolution_strength", strength);
        }, 100, mDissolutionTime).onComplete = () => GameManager.GetInstance().Lose();
    }
    /// <summary>
    /// 等待几秒再到下一回合
    /// </summary>
    /// <param name="time"></param>
    /// <returns></returns>
    private IEnumerator ReadyForNextRound(float time)
    {
        //MonoManager.GetInstance().AddFixedUpdateListener();
        yield return new WaitForSeconds(time);
        GameManager.GetInstance().isNextRound = true;
    }
}
